package cc.lotuscard;

import java.util.HashMap;

import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;

public class LotusCard {

	/** address of UserAccount */
	public static final int ADDR_ACCOUNT = 1;
	/** address of UserSex/Age */
	public static final int ADDR_SEX_AGE = 2;
	/** address of UserHeight */
	public static final int ADDR_HEIGHT = 4;
	/** address of UserWeight */
	public static final int ADDR_WEIGHT = 5;
	/** address of UserFatContent */
	public static final int ADDR_FAT_CONTENT = 6;
	/** address of MODE1 Times */
	public static final int ADDR_MODE_ADD_MUSCLE_TIMES = 8;
	/** address of MODE2 Times */
	public static final int ADDR_MODE_REDUCE_FAT_TIMES = 9;
	/** address of MODE3 Times */
	public static final int ADDR_MODE_BODYBUILDING_TIMES = 10;
	/** address of MODE4 Times */
	public static final int ADDR_MODE_ADD_FORCE_TIMES = 12;

	private Context mContext;
	public LotusCardDriver mLotusCardDriver;
	private int nDeviceHandle = 0;

	private UsbManager m_UsbManager = null;
	private UsbDevice m_LotusCardDevice = null;
	private UsbInterface m_LotusCardInterface = null;
	private UsbDeviceConnection m_LotusCardDeviceConnection = null;
	private final int m_nVID = 1306;
	private final int m_nPID = 20763;
	private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";

	public LotusCard(Context context) {
		if (mLotusCardDriver == null) {
			mLotusCardDriver = new LotusCardDriver();
		}
		mContext = context;
	}

	public boolean initCardReading() {
		// 设置USB读写回调 串口可以不用此操作
		SetUsbCallBack();
		nDeviceHandle = mLotusCardDriver.OpenDevice("", 0, 0, true);

		if (nDeviceHandle > 0) {
			boolean result = mLotusCardDriver.Beep(nDeviceHandle, 0);
			return result;
		}
		return false;
	}
	
	public String getCardNo() {

		if(nDeviceHandle>0)
		{
			boolean bResult = false;
			LotusCardParam tLotusCardParam1 = new LotusCardParam();
	//		bResult = mLotusCardDriver.Beep(nDeviceHandle, 10);
	//		Toast.makeText(mContext, "Beep " + String.valueOf(bResult) , Toast.LENGTH_LONG).show();
	//		if (!bResult) {
	//			return "";
	//		}

			int nRequestType = LotusCardDriver.RT_NOT_HALT;
			bResult = mLotusCardDriver.GetCardNo(nDeviceHandle, nRequestType,
					tLotusCardParam1);
			if(bResult)
			{
				long sx = bytes2long(tLotusCardParam1.arrCardNo);
				bResult = mLotusCardDriver.Beep(nDeviceHandle, 10);
				return sx+"";
			}
			else
			{
				return "";
			}
		}
		else
		{
			return "";
		}
	}
	
	public static long bytes2long(byte[] byteNum) {
		long num = 0;
		for (int ix = 0; ix < 4; ++ix) {
			num <<= 8;
			if (byteNum[ix] < 0) {
				num |= (256 + (byteNum[ix]) & 0xff);
			} else {
				num |= (byteNum[ix] & 0xff);
			}
		}
		return num;
	}

	/**
	 * get the saved data from card address
	 * @param addr
	 * @return the data from card
	 */
	public String getDateFromCard(int addr) {
		LotusCardParam cardParam = new LotusCardParam();
		boolean bResult = testCard(cardParam);
		if (!bResult) {
			return "";
		}
		
		bResult = mLotusCardDriver.Read(nDeviceHandle, addr, cardParam);
		if (!bResult) {
			return "";
		}
		
		if (bResult) {
			return "";
		} else {
			return bytes2long(cardParam.arrBuffer) + "";
		}
	}
	
	public boolean writeDateToCard(int addr, String str) {
		LotusCardParam cardParam = new LotusCardParam();
		boolean bResult = testCard(cardParam);
		if (!bResult) {
			return false;
		}
		cardParam.arrBuffer = str.getBytes();

		cardParam.nBufferSize = cardParam.arrBuffer.length;
		bResult = mLotusCardDriver.Write(nDeviceHandle, addr, cardParam);
		return bResult;
	}
	
	public boolean increment(int addr) {
		return mLotusCardDriver.Increment(nDeviceHandle, addr, 1);
	}
	
	private boolean testCard(LotusCardParam cardParam){
		boolean bResult = false;
		if (!(nDeviceHandle > 0)) {
			return false;
		}

		int nRequestType = LotusCardDriver.RT_NOT_HALT;
		bResult = mLotusCardDriver.Request(nDeviceHandle, nRequestType,
				cardParam);
		if (!bResult) {
			return bResult;
		}
		bResult = mLotusCardDriver.Anticoll(nDeviceHandle, cardParam);
		if (!bResult) {
			return bResult;
		}

		bResult = mLotusCardDriver.Select(nDeviceHandle, cardParam);
		if (!bResult) {
			return bResult;
		}

		cardParam.arrKeys[0] = (byte) 0xff;
		cardParam.arrKeys[1] = (byte) 0xff;
		cardParam.arrKeys[2] = (byte) 0xff;
		cardParam.arrKeys[3] = (byte) 0xff;
		cardParam.arrKeys[4] = (byte) 0xff;
		cardParam.arrKeys[5] = (byte) 0xff;
		cardParam.nKeysSize = 6;
		bResult = mLotusCardDriver.LoadKey(nDeviceHandle, LotusCardDriver.AM_A,
				0, cardParam);
		if (!bResult) {
			return bResult;
		}
		bResult = mLotusCardDriver.Authentication(nDeviceHandle,
				LotusCardDriver.AM_A, 0, cardParam);
		if (!bResult) {
			return bResult;
		}
		return true;
	}

	private void testIcCardReader(int nDeviceHandle) {
		boolean bResult = false;
		int nRequestType;
		LotusCardParam cardParam = new LotusCardParam();
		bResult = mLotusCardDriver.Beep(nDeviceHandle, 10);
		bResult = mLotusCardDriver.Beep(nDeviceHandle, 10);
		if (!bResult) {
			return;			
		}
		nRequestType = LotusCardDriver.RT_NOT_HALT;
		// Replace GetCardNo with the 3 methods below
		// bResult = mLotusCardDriver.Request(nDeviceHandle, nRequestType,
		// cardParam1);
		// if (!bResult)
		// return;
		// bResult = mLotusCardDriver.Anticoll(nDeviceHandle, cardParam1);
		// if (!bResult)
		// return;
		// bResult = mLotusCardDriver.Select(nDeviceHandle, cardParam1);
		// if (!bResult)
		// return;
		bResult = mLotusCardDriver.GetCardNo(nDeviceHandle, nRequestType,
				cardParam);
		if (!bResult)
			return;
		cardParam.arrKeys[0] = (byte) 0xff;
		cardParam.arrKeys[1] = (byte) 0xff;
		cardParam.arrKeys[2] = (byte) 0xff;
		cardParam.arrKeys[3] = (byte) 0xff;
		cardParam.arrKeys[4] = (byte) 0xff;
		cardParam.arrKeys[5] = (byte) 0xff;
		cardParam.nKeysSize = 6;
		bResult = mLotusCardDriver.LoadKey(nDeviceHandle, LotusCardDriver.AM_A,
				0, cardParam);
		if (!bResult)
			return;
		bResult = mLotusCardDriver.Authentication(nDeviceHandle,
				LotusCardDriver.AM_A, 0, cardParam);
		if (!bResult)
			return;
		bResult = mLotusCardDriver.Read(nDeviceHandle, 1, cardParam);
		if (!bResult)
			return;

		cardParam.arrBuffer[0] = (byte) 0x10;
		cardParam.arrBuffer[1] = (byte) 0x01;
		cardParam.arrBuffer[2] = (byte) 0x02;
		cardParam.arrBuffer[3] = (byte) 0x03;
		cardParam.arrBuffer[4] = (byte) 0x04;
		cardParam.arrBuffer[5] = (byte) 0x05;
		cardParam.arrBuffer[6] = (byte) 0x06;
		cardParam.arrBuffer[7] = (byte) 0x07;
		cardParam.arrBuffer[8] = (byte) 0x08;
		cardParam.arrBuffer[9] = (byte) 0x09;
		cardParam.arrBuffer[10] = (byte) 0x0a;
		cardParam.arrBuffer[11] = (byte) 0x0b;
		cardParam.arrBuffer[12] = (byte) 0x0c;
		cardParam.arrBuffer[13] = (byte) 0x0d;
		cardParam.arrBuffer[14] = (byte) 0x0e;
		cardParam.arrBuffer[15] = (byte) 0x0f;
		cardParam.nBufferSize = 16;
		bResult = mLotusCardDriver.Write(nDeviceHandle, 1, cardParam);
		if (!bResult)
			return;
	}

	private void SetUsbCallBack() {
		PendingIntent pendingIntent;
		pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(
				ACTION_USB_PERMISSION), 0);
		m_UsbManager = (UsbManager) mContext.getSystemService("usb");
		if (m_UsbManager == null)
			return;

		HashMap<String, UsbDevice> deviceList = m_UsbManager.getDeviceList();
		if (!deviceList.isEmpty()) {
			for (UsbDevice device : deviceList.values()) {
				if ((m_nVID == device.getVendorId())
						&& (m_nPID == device.getProductId())) {
					m_LotusCardDevice = device;
					break;
				}
			}
		}
		if (null == m_LotusCardDevice) {
			return;			
		}
		m_LotusCardInterface = m_LotusCardDevice.getInterface(0);
		if (null == m_LotusCardInterface) {
			return;			
		}
		if (false == m_UsbManager.hasPermission(m_LotusCardDevice)) {
			m_UsbManager.requestPermission(m_LotusCardDevice, pendingIntent);
		}
		UsbDeviceConnection conn = null;
		if (m_UsbManager.hasPermission(m_LotusCardDevice)) {
			conn = m_UsbManager.openDevice(m_LotusCardDevice);
		}

		if (null == conn) {
			return;			
		}

		if (conn.claimInterface(m_LotusCardInterface, true)) {
			m_LotusCardDeviceConnection = conn;
		} else {
			conn.close();
		}
		if (null == m_LotusCardDeviceConnection)
			return;
		// 把上面获取的对性设置到接口中用于回调操作
		LotusCardDriver.m_UsbDeviceConnection = m_LotusCardDeviceConnection;
		if (m_LotusCardInterface.getEndpoint(1) != null) {
			LotusCardDriver.m_OutEndpoint = m_LotusCardInterface.getEndpoint(1);
		}
		if (m_LotusCardInterface.getEndpoint(0) != null) {
			LotusCardDriver.m_InEndpoint = m_LotusCardInterface.getEndpoint(0);
		}
	}
}